package com.ffmpeg.opt.common.ffmpeg.handler;


import cn.hutool.cache.impl.TimedCache;
import com.ffmpeg.opt.common.utils.CalcUtil;
import lombok.extern.slf4j.Slf4j;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 视频转换消息输出处理
 *
 * @author eguid
 * @version 2017年10月13日
 * @since jdk1.7
 */
@Slf4j
public class MovieCovertHandlerMethod implements OutHandlerMethod {

    public static final Pattern durationPattern = Pattern.compile("Duration:[^,]*");

    public static final Pattern timePattern = Pattern.compile("time=[^\\s]*\\s{1}");

    /**
     * 存放任务进度
     */
    public static final TimedCache<String, MovieTask> taskBean = new TimedCache<>((60 * 1000) * 60 * 3);


    /**
     * 任务是否异常中断，如果
     */
    public boolean isBroken = false;

    @Override
    public void parse(String id, String msg) {
        MovieTask movieTask = taskBean.get(id);
        log.info("{}消息:{}", id, msg);
        //过滤消息
        if (msg.indexOf("fail") != -1) {
            log.info(id + "任务可能发生故障：" + msg);
            log.info("失败，设置中断状态");
            isBroken = true;
        } else if (msg.indexOf("miss") != -1) {
            log.info(id + "任务可能发生丢包：" + msg);
            log.info("失败，设置中断状态");
            isBroken = true;
        } else {
            isBroken = false;
            Long duration = movieTask.getDuration();
            duration = duration == null ? 0 : duration;
            if (duration == 0) {
                getDuration(id, msg);
            }
            if (duration != 0) {
                if (movieTask.getTaskType().equals("初始：获取时长")) {
                    return;
                }
                double curTime = currentTime(msg);
                if (curTime == 0) {
                    return;
                }
                double proess = CalcUtil.div(curTime, duration).mul(100).doubleValue(2);
                boolean success = movieTask.isSuccess();
                if (!success) {
                    movieTask.setProess(proess);
                    String info = movieTask.getTaskType() + " 进度：" + proess + "%";
                    log.info("[ " + id + " ] " + info);
                }
                taskBean.put(id, movieTask);
                if (proess >= 100) {
                    success = true;
                }

            }
        }

    }

    private void getDuration(String id, String msg) {
        Matcher matcher = durationPattern.matcher(msg);
        long second = 1;
        long minute = second * 60;
        long hour = minute * 60;
        while (matcher.find()) {
            String timeStr = matcher.group();
            if (timeStr != null) {
                String replace = timeStr.replace("Duration:", "");
                String[] split = replace.split(":");
                int hourTemp = Integer.parseInt(split[0].trim());
                int minuteTemp = Integer.parseInt(split[1].trim());
                Double secondTemp = Double.parseDouble(split[2].trim());
                long duration = hourTemp * 60 * 60 + minuteTemp * 60 + secondTemp.longValue();
                MovieTask movieTask = taskBean.get(id);
                movieTask.setDuration(duration);
                taskBean.put(id, movieTask);
            }
        }
    }

    private long currentTime(String msg) {
        Matcher matcher = timePattern.matcher(msg);
        long second = 1;
        long minute = second * 60;
        long hour = minute * 60;
        while (matcher.find()) {
            String timeStr = matcher.group();
            if (timeStr != null) {
                String replace = timeStr.replace("time=", "");
                String[] split = replace.split(":");
                int hourTemp = Integer.parseInt(split[0].trim());
                int minuteTemp = Integer.parseInt(split[1].trim());
                Double secondTemp = Double.parseDouble(split[2].trim());
                Double ceil = Math.ceil(secondTemp);
                return hourTemp * 60 * 60 + minuteTemp * 60 + ceil.intValue();
            }
        }
        return 0;
    }

    @Override
    public boolean isbroken() {
        return isBroken;
    }

    public static void stop(String taskId) {
        taskBean.remove(taskId);
    }
}
